using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._SpatialAnalystTools._Hydrology
{
    /// <summary>
    /// <para>Flow Direction</para>
    /// <para>Creates a raster of flow direction from each cell to its downslope neighbor, or neighbors, using the D8, Multiple Flow Direction (MFD), or D-Infinity (DINF) method.</para>
    /// <para>使用 D8、多流向 （MFD） 或 D-无穷大 （DINF） 方法创建从每个像元到其下坡相邻节点的流向栅格。</para>
    /// </summary>    
    [DisplayName("Flow Direction")]
    public class FlowDirection : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public FlowDirection()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_in_surface_raster">
        /// <para>Input surface raster</para>
        /// <para>The input raster representing a continuous surface.</para>
        /// <para>表示连续表面的输入栅格。</para>
        /// </param>
        /// <param name="_out_flow_direction_raster">
        /// <para>Output flow direction raster</para>
        /// <para><xdoc>
        ///   <para>The output raster that shows the flow direction from each cell to its downslope neighbor(s) using D8, Multiple Flow Direction (MFD) or D-Infinity (DINF) methods.</para>
        ///   <para>This output is of integer type.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>使用 D8、多流向 （MFD） 或 D-无穷远 （DINF） 方法显示从每个像元到其下坡相邻单元的流向的输出栅格。</para>
        ///   <para>此输出为整数类型。</para>
        /// </xdoc></para>
        /// </param>
        public FlowDirection(object _in_surface_raster, object _out_flow_direction_raster)
        {
            this._in_surface_raster = _in_surface_raster;
            this._out_flow_direction_raster = _out_flow_direction_raster;
        }
        public override string ToolboxName => "Spatial Analyst Tools";

        public override string ToolName => "Flow Direction";

        public override string CallName => "sa.FlowDirection";

        public override List<string> AcceptEnvironments => ["autoCommit", "cellSize", "cellSizeProjectionMethod", "compression", "configKeyword", "extent", "geographicTransformations", "mask", "outputCoordinateSystem", "parallelProcessingFactor", "scratchWorkspace", "snapRaster", "tileSize", "workspace"];

        public override object[] ParameterInfo => [_in_surface_raster, _out_flow_direction_raster, _force_flow.GetGPValue(), _out_drop_raster, _flow_direction_type.GetGPValue()];

        /// <summary>
        /// <para>Input surface raster</para>
        /// <para>The input raster representing a continuous surface.</para>
        /// <para>表示连续表面的输入栅格。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input surface raster")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _in_surface_raster { get; set; }


        /// <summary>
        /// <para>Output flow direction raster</para>
        /// <para><xdoc>
        ///   <para>The output raster that shows the flow direction from each cell to its downslope neighbor(s) using D8, Multiple Flow Direction (MFD) or D-Infinity (DINF) methods.</para>
        ///   <para>This output is of integer type.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>使用 D8、多流向 （MFD） 或 D-无穷远 （DINF） 方法显示从每个像元到其下坡相邻单元的流向的输出栅格。</para>
        ///   <para>此输出为整数类型。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output flow direction raster")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _out_flow_direction_raster { get; set; }


        /// <summary>
        /// <para>Force all edge cells to flow outward</para>
        /// <para><xdoc>
        ///   <para>Specifies if edge cells will always flow outward or follow normal flow rules.</para>
        ///   <bulletList>
        ///     <bullet_item>Unchecked—If the maximum drop on the inside of an edge cell is greater than zero, the flow direction will be determined as usual; otherwise, the flow direction will be toward the edge. Cells that should flow from the edge of the surface raster inward will do so. This is the default.</bullet_item><para/>
        ///     <bullet_item>Checked—All cells at the edge of the surface raster will flow outward from the surface raster.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定边像元是始终向外流动还是遵循正常流动规则。</para>
        ///   <bulletList>
        ///     <bullet_item>未选中 （Uncted） - 如果边像元内部的最大落差大于零，则将照常确定流动方向;否则，流向将朝向边缘。应从表面栅格边缘向内流动的像元将这样做。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>选中 - 表面栅格边缘的所有像元都将从表面栅格向外流动。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Force all edge cells to flow outward")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _force_flow_value _force_flow { get; set; } = _force_flow_value._false;

        public enum _force_flow_value
        {
            /// <summary>
            /// <para>NORMAL</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NORMAL")]
            [GPEnumValue("false")]
            _false,

            /// <summary>
            /// <para>FORCE</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("FORCE")]
            [GPEnumValue("true")]
            _true,

        }

        /// <summary>
        /// <para>Output drop raster</para>
        /// <para><xdoc>
        ///   <para>An optional output drop raster.</para>
        ///   <para>The drop raster returns the ratio of the maximum change in elevation from each cell along the direction of flow to the path length between centers of cells, expressed in percentages.</para>
        ///   <para>This output is of floating-point type.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>可选的输出放置栅格。</para>
        ///   <para>下降栅格将返回每个像元沿流动方向的最大高程变化与像元中心之间的路径长度之比，以百分比表示。</para>
        ///   <para>此输出为浮点型。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output drop raster")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _out_drop_raster { get; set; } = null;


        /// <summary>
        /// <para>Flow direction type</para>
        /// <para><xdoc>
        ///   <para>Specifies the type of flow method to use while computing flow directions.</para>
        ///   <bulletList>
        ///     <bullet_item>D8—Assign a flow direction based on the D8 flow method. This method assigns flow direction to the steepest downslope neighbor. This is the default.</bullet_item><para/>
        ///     <bullet_item>MFD—Assign a flow direction based on the MFD flow method. This method assigns multiple flow directions towards all downslope neighbors.</bullet_item><para/>
        ///     <bullet_item>DINF—Assign a flow direction based on the D-Infinity flow method using the steepest slope of a triangular facet.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定计算流向时要使用的流方法的类型。</para>
        ///   <bulletList>
        ///     <bullet_item>D8 - 根据 D8 流法指定流向。此方法将流向分配给最陡峭的下坡邻居。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>MFD - 根据 MFD 流方法指定流向。此方法将多个流向所有下坡邻居。</bullet_item><para/>
        ///     <bullet_item>DINF - 使用三角形面的最陡坡，根据 D-Infinity 流动方法指定流向。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Flow direction type")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _flow_direction_type_value _flow_direction_type { get; set; } = _flow_direction_type_value._D8;

        public enum _flow_direction_type_value
        {
            /// <summary>
            /// <para>D8</para>
            /// <para>D8—Assign a flow direction based on the D8 flow method. This method assigns flow direction to the steepest downslope neighbor. This is the default.</para>
            /// <para>D8 - 根据 D8 流法指定流向。此方法将流向分配给最陡峭的下坡邻居。这是默认设置。</para>
            /// </summary>
            [Description("D8")]
            [GPEnumValue("D8")]
            _D8,

            /// <summary>
            /// <para>MFD</para>
            /// <para>MFD—Assign a flow direction based on the MFD flow method. This method assigns multiple flow directions towards all downslope neighbors.</para>
            /// <para>MFD - 根据 MFD 流方法指定流向。此方法将多个流向所有下坡邻居。</para>
            /// </summary>
            [Description("MFD")]
            [GPEnumValue("MFD")]
            _MFD,

            /// <summary>
            /// <para>DINF</para>
            /// <para>DINF—Assign a flow direction based on the D-Infinity flow method using the steepest slope of a triangular facet.</para>
            /// <para>DINF - 使用三角形面的最陡坡，根据 D-Infinity 流动方法指定流向。</para>
            /// </summary>
            [Description("DINF")]
            [GPEnumValue("DINF")]
            _DINF,

        }

        public FlowDirection SetEnv(int? autoCommit = null, object cellSize = null, object compression = null, object configKeyword = null, object extent = null, object geographicTransformations = null, object mask = null, object outputCoordinateSystem = null, object parallelProcessingFactor = null, object scratchWorkspace = null, object snapRaster = null, double[] tileSize = null, object workspace = null)
        {
            base.SetEnv(autoCommit: autoCommit, cellSize: cellSize, compression: compression, configKeyword: configKeyword, extent: extent, geographicTransformations: geographicTransformations, mask: mask, outputCoordinateSystem: outputCoordinateSystem, parallelProcessingFactor: parallelProcessingFactor, scratchWorkspace: scratchWorkspace, snapRaster: snapRaster, tileSize: tileSize, workspace: workspace);
            return this;
        }

    }

}